三周学会小程序第六讲:登录优化和存储用户信息
上一讲主要讲解了微信小程序登录的原理和实现《三周学会小程序第五讲:登录的原理和实现》,这一讲主要是对登录流程进行优化,同时登录成功后把用户信息存入服务器端数据库。这一讲涉及的服务端知识比较多,比如 Flyway
、 H2
、 MyBatis
、 MyBatisGenerator
等使用。
登录优化
1,把获取 code
的逻辑放到 app.js
。app.js
的 onLaunch
方法是小程序的加载入口,这样可以全局的控制登录态和 code
的获取,首先判断当前用户是否已经有 token
,如果有就不需要获取 code
和 登录逻辑。
let token = wx.getStorageSync("token") || "";
this.globalData.token = token;
// 登录接口,获取到 code 存到 data 里面
// 用于获取到code传递给服务器端
if (!token){
wx.login({
success: codeInfo => {
console.log(codeInfo);
this.globalData.code = codeInfo.code;
}
});
}
可以通过微信的控制台查看 storage
的存储情况。
调用服务器端登录接口失败以后需要重新调用 app.login();
方法,因为一个 code
只能使用一次。
H2
H2
是一个超轻量级的数据库,引入一个 1.5M
的 jar
就可以运行使用,同时支持 JDBC
,内嵌,内存和服务三种模式,这样引入 H2
以后我们就可以方便的在本地调试项目了。
第一步,直接在 pom.xml
引入依赖
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.196</version>
</dependency>
第二步,直接在 application.yml
本地配置里面配置好,然后就可以在下文中的 MyBatis
里面使用配置连接池了
db:
url: jdbc:h2:~/jiuask
username: sa
password: sa
driver: org.h2.Driver
当前采用的链接方式是内嵌连接,不需要启动服务,并且会保留数据,当然这种连接方式有一个问题,它只允许一个连接,所以每次你想通过其他工具读取数据的时候需要关掉程序的连接。
MyBatis
MyBatis
就不用详细讲解了,目前比较成熟的数据库框架,我们直接讲解配置,小编使用了 druid
连接池。
第一步,一如既往的引入 pom.xml
文件
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
直接在 applicationContext.xml
里面配置即可。
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 基本属性 url、user、password -->
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="1"/>
<property name="driverClassName" value="${db.driver}"/>
<property name="minIdle" value="1"/>
<property name="maxActive" value="1"/>
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000"/>
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000"/>
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000"/>
<property name="validationQuery" value="SELECT 'x'"/>
<property name="testWhileIdle" value="true"/>
<property name="testOnBorrow" value="false"/>
<property name="testOnReturn" value="false"/>
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="false"/>
<property name="maxPoolPreparedStatementPerConnectionSize" value="20"/>
<!-- 配置监控统计拦截的filters -->
<property name="filters" value="stat"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- 自动扫描mapping.xml文件,**表示迭代查找,也可在sqlMapConfig.xml中单独指定xml文件-->
<property name="mapperLocations" value="classpath:mybatis/mapping/*.xml"/>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.codedrinker.dao"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
上面注释很全,dataSource
是数据源。sqlSessionFactory
是 session 工厂,用户注入 mapper 使用。MapperScannerConfigurer
是为了自动扫描对应包下面的 Mapper
装置到 Bean
里面。如果这个地方不明白可以看一下小编之前的一篇文章
《从 Spring 集成 MyBatis 浅析 Java动态代理》
值得注意的地方是 mapperLocations
配置的路径,是不是每次都需要我们手写 *.xml
和 N 多对象啊?答案是不需要的,我们使用 MyBatisGenerator
自动生成。怎么生成?看下文。
Flyway
Flyway
是一个数据库 Migration
工具,为什么引入这个工具呢?举个例子,如果你有3个环境:开发、UAT和线上;你有4个开发人员,每个人有自己的一个开发环境,这些环境都有一个自己的数据库,那么你是不是每次有数据库变更都需要让他们去执行以下脚本?不仅麻烦而且出错率特别高。
那么 Flyway
就应运而生,它可以帮你记录,执行你的 SQL
变更,只需要引入它的依赖,就可以帮你精准的维护数据库脚本的变更。使用 Flyway
方式有多种,命令行、Maven命令、Java API和Spring 配置,我们采用 Spring 配置的方式,这样不需要每一个部署环境安装命令行或者是 Maven 工具。具体操作如下
第一步还是添加依赖到 pom.xml
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>5.2.3</version>
</dependency>
第二步配置 applicationContext.xml
,在刚才配置的地方追加如下配置
<bean id="flywayConfig" class="org.flywaydb.core.api.configuration.ClassicConfiguration">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="flyway" class="org.flywaydb.core.Flyway" init-method="migrate">
<constructor-arg ref="flywayConfig"/>
</bean>
flywayConfig
是配置 dataSource
给 flyway
,这样他们就可以共用数据源了。flyway
是执行 migrate
的入口。
最后需要在 sqlSessionFactory
添加一个 depends-on="flyway"
这样便可以在创建工厂的时候执行数据库脚本了。
第三步,配置数据库脚本, Flyway
命令运行的时候会默认找 resources/db/migration
文件下面的 *.sql
文件,因为数据库脚本执行是需要有顺序并且唯一,所以数据库脚本有一个命名规则,就是从 V1__**
开始,依次是 V2__**
。比如小编目前正要创建一个 user
表,所以我的命名需要是 V1__Create_user_table.sql
。
第四步,直接运行项目 Application.java
文件,我们会在控制台看到如下打印信息,说明成功执行了脚本。
Flyway 5.2.3 by Boxfuse
Database: jdbc:h2:~/jiuask (H2 1.4)
Validated 1 migration (execution time 00:00.029s)
Creating Metadata table: "PUBLIC"."schema_version"
Current version of schema "PUBLIC": << Empty Schema >>
Migrating schema "PUBLIC" to version 1 - Create user table
Successfully applied 1 migration to schema "PUBLIC" (execution time
那么怎么验证一下呢?我们可以通过 Idea
自带的数据库连接工具按照如下方式连接一下(记得关闭项目)
便可以看到我们刚才创建的user表,同时会有一个 schema_version
表,这个表就是 flyway
用于存储数据库脚本是否已经执行过的依据,避免重复执行和错误的修改。所以后面你需要修改数据库,必须添加新的脚本,不能修改原有的。
MyBatis-Generator
MyBatis-Generator
的目的就是通过创建好的数据库,逆向生成 model
、 mapper
和 xml
的工具,这样可以大大减少我们的工作量。
第一步,添加 Maven
的插件,用于运行 generator
。
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.7</version>
<configuration>
<configurationFile>${project.basedir}/src/main/resources/generatorConfig.xml</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
第二步,配置 generatorConfig.xml
文件,该文件主要是用于指定 model
、 mapper
和 xml
等文件的生成路径和规则,详细信息就不罗列了,可以直接参照源码。重点讲解一下 classPathEntry
需要指定一下你当前使用的 h2.jar
的存放位置。 jdbcConnection
和上文中我们配置的 h2
的地址一致。后面如果有多个数据库表,直接添加 table
标签即可。
第三步,运行如下命令,就会自动生成对应的文件。
mvn mybatis-generator:generate
服务端存储 Token 和 用户信息
截止到上面基础工作已经全部搞定,下面我们实现登录成功存储数据库的逻辑,这便是非常简单的事情。
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public void saveOrUpdate(User user) {
UserExample example = new UserExample();
example.createCriteria().andOpenidEqualTo(user.getOpenid());
List<User> users = userMapper.selectByExample(example);
if (users != null && users.size() != 0) {
user.setGmtModified(System.currentTimeMillis());
userMapper.updateByExampleSelective(user, example);
} else {
user.setGmtCreate(System.currentTimeMillis());
user.setGmtModified(System.currentTimeMillis());
userMapper.insert(user);
}
}
}
一段代码就搞定了这件事情。 UserExample.createCriteria
的方法是 generator
提供的可以组装 sql
的工具,上面的逻辑是先通过 openid
查询数据库中是否已经存在,如果存在就更新,否则创建。
这样以后重启服务器,再次点击小程序的登录按钮,你会看到神奇的一幕,提示“登录成功”,这样你的第一个前后端交互小程序就搞定了。
作业
好久没有留作业了,这次的作业就是如果你使用的是 MySQL
数据库,那么尝试使用 MySQL
把项目运行起来。
源码
小程序源码地址,Tag V6
https://github.com/codedrinker/jiuask
服务端源码地址,Tag V6
https://github.com/codedrinker/jiuask-server
我是浪漫的分割线
问答
如果您对本系列文章有兴趣,欢迎置顶本订阅号,第一时间获取更新。
如果有任何问题,欢迎留言,小编很热衷和大家一起讨论技术问题。
另外小编创建了一个技术交流群,请添加小编微信,切记备注“小程序”,小编拉你进去。【只讨论技术,非诚勿扰】